# aem.two_d.transient.well -- 
#
# Copyright (c) 2000, V.Kelson and M.Bakker
#           (c) 2001, Willem Jan Zaadnoordijk

from types import *

import geometry
XY = geometry.XY
SearchableList = geometry.two_d.collections.SearchableList

import base

import aem.container
RowList = aem.container.RowList
ColumnList = aem.container.ColumnList
 
class Well(geometry.two_d.Circle,base.Element):
	'''Class for transient wells

	Python call: Well(xc,yc,radius,tQlist=[geometry.XY(0,0)],parent=None)

	Attributes:

	  - xc,yc: location of well (inherited from Circle)
	  - radius: radius of well (inherited from Circle)
	  - tQlist:  list of pairs (time, discharge)
	  - parent: parent of the element (inherited from Element)
	  - elementList: list of transient elements ("UnitStepWell"s)
	  - initialSteadyState: list of initial steady element(s)
	    this element is not included in 'parameters'and 'elementList'
	    and does not appear in the influence functions

	Overloaded functions from Element: __init__,
	                                   potentialInfluence, dischargeInfluence
	'''
	
	def __init__(self,xc,yc,radius,tQlist=[geometry.XY(0,0)],parent=None):
		'''Constructor'''
		geometry.two_d.Circle.__init__(self,xc,yc,radius)
		base.Element.__init__(self,parent)
		self.elementList = SearchableList()
		self.__numberOfParameters = 0
		self.parameters=ColumnList([])
		self.initialQ = 0
		oldQ=0
		for partim in tQlist :
			if partim.x <= 0 :
				if partim.y != 0 :
					if self.initialQ == 0:
						self.initialSteadyState = \
							aem.two_d.single.Well(xc,yc,radius, \
							                 partim.y,parent.initialSteadyState)
						self.initialQ = partim.y
					else:
						self.initialSteadyState.parameters = ColumnList([partim.y])
						self.initialQ = partim.y
			else :
				self.__numberOfParameters = self.__numberOfParameters+1
				dQ=partim.y-oldQ
				aem.two_d.transient.UnitStepWell(partim.x,self)
				self.parameters.append(dQ)
			oldQ=partim.y

	def __repr__(self):
#		# Parent not yet included
#		string = 'Well' + str((self.center.x,self.center.y,self.radius))
#		print string
#		for el in self.elementList:
#			string = string + el.__repr__()
#			print string
#		return string
		return 'Trans.Well{'    \
		   + str((self.center.x,self.center.y,self.radius, \
		         self.parameters,self.elementList))        \
		   + '}'

	def addElement(self,el):
		self.elementList.append(el)

	def potentialInfluence(self,xy,t):
		assert isinstance(xy,XY),"XY point is required"
		pot = []
		self.alpha = self.parent.aquiferDiffusivity(xy,t)
		if self.isInArea(xy):
			xyw = XY( self.radius , 0 )
		else:
			xyw = XY( xy.x-self.zc.real , xy.y-self.zc.imag )
		for el in self.elementList:
			pot = pot + el.potentialInfluence(xyw,t)
		return RowList( pot )

	def dischargeInfluence(self,xy,t):
		assert isinstance(xy,XY),"XY point is required"
		dis = []
		self.alpha = self.parent.aquiferDiffusivity(xy,t)
		if self.isInArea(xy):
			xyw = XY( self.radius,0)
		else:
			xyw = XY( xy.x-self.zc.real , xy.y-self.zc.imag )
		for el in self.elementList :
			dis = dis+el.dischargeInfluence(xyw,t)
		return RowList( dis )
